""" 
功能:
视频播放器
暂停/播放, 快进, 快退, 打开视频文件, 音量调节

前置教程:


"""

import sys
import os
import glob
import pathlib
import time
import threading
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QWidget, QFileDialog
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import Qt
import vlc
from video_player_ui import *
from dataclasses import dataclass


@dataclass
class videoInfo:
    path: str
    duration: int
    width: int
    height: int
    stat: str = "none"


class vlcPlayer(Ui_Form):
    def __init__(self, form):
        super().__init__()
        self.widgets = form
        self.setupUi(form)
        self.vlc_init()
        self.ui_and_callback_init()

    def vlc_init(self):
        self.instance = vlc.Instance()
        self.player = self.instance.media_player_new()
        self.btn_play_pause_value = "play"
        self.video_info = None

    def ui_and_callback_init(self):
        self.btn_open_video.clicked.connect(self.open_file)
        self.btn_play_puse.clicked.connect(self.vlc_play_pause)
        self.btn_forward.clicked.connect(self.vlc_forward)
        self.btn_backword.clicked.connect(self.vlc_backward)
        self.slider_vol.sliderReleased.connect(self.vlc_vol_change)
        self.slider_progress.sliderReleased.connect(self.vlc_progress_change)
        vol_num = self.slider_vol.value()
        self.label_vol.setText(str(vol_num))
        # 设置焦点为widgets
        self.widgets.setFocusPolicy(Qt.StrongFocus)
        
        # 启动定时线程: 更新播放进度条
        self.timer_task = threading.Thread(target=self.vlc_timer_task, daemon=True)
        self.timer_task.start()

    def open_file(self):
        filename, _ = QFileDialog.getOpenFileName(
            self.widgets,
            "Open Video",
            "",
            "Video Files (*.mp4 *.flv *.ts *.mts *.avi *.mkv)",
        )
        if filename != "":
            self.media = self.instance.media_new(filename)
            self.player.set_media(self.media)

            if sys.platform == "darwin":  # MacOS
                self.player.set_nsobject(int(self.video_frame.winId()))
            elif sys.platform == "win32":  # Windows
                self.player.set_hwnd(int(self.video_frame.winId()))
            else:  # Linux
                self.player.set_xwindow(int(self.video_frame.winId()))

            self.player.play()
            time.sleep(1)
            self.get_video_info()

    def get_player_status(self):
        progress = self.player.get_position() * 100  # 进度 0~1
        lendth_ms = self.player.get_length()  # 视频长度 ms
        cur_time_ms = self.player.get_time()  # 当前播放时间 ms

    def get_video_info(self):
        path = pathlib.Path(self.media.get_mrl()).name
        duration = self.player.get_length()
        width = self.player.video_get_width()
        height = self.player.video_get_height()
        video_info = videoInfo(path, duration, width, height)
        print(video_info)
        self.video_info = video_info

    # 播放/暂停
    def vlc_play_pause(self):
        if self.btn_play_pause_value == "play":
            self.player.pause()
            self.btn_play_pause_value = "pause"
        else:
            self.player.play()
            self.btn_play_pause_value = "play"

    # 快进
    def vlc_forward(self):
        self.player.set_time(self.player.get_time() + 5000)

    # 后退
    def vlc_backward(self):
        self.player.set_time(self.player.get_time() - 5000)

    # 音量
    def vlc_vol_change(self):
        value = self.slider_vol.value()
        self.vlc_adjust_vol(value)

    def vlc_adjust_vol(self, value):
        cur_vol = self.slider_vol.value()
        new_vol = cur_vol + value
        # 限制音量在 0 到 100 之间
        if new_vol > 100:
            new_vol = 100
        elif new_vol < 0:
            new_vol = 0
        self.player.audio_set_volume(new_vol)
        self.slider_vol.setValue(new_vol)
        self.label_vol.setText(str(new_vol))

    # 画面缩放
    def adjust_ui_layout(self, key=None):
        scaling = 1
        if key == Qt.Key_1:
            scaling = 0.5
        elif key == Qt.Key_2:
            scaling = 1
        elif key == Qt.Key_3:
            scaling = 1.5
        elif key == Qt.Key_4:
            scaling = 2
        if not self.player.is_playing():
            print("视频未播放")
            return
        width = int(self.video_info.width * scaling)
        height = int(self.video_info.height * scaling)
        print(f"调整视频大小为: {width}x{height}")
        self.player.pause()
        self.widgets.resize(width, height + 100)
        self.video_frame.setGeometry(0, 0, width, height)
        self.horizontalLayoutWidget.setGeometry(0, height, width, 100)
        self.slider_progress.setGeometry(QtCore.QRect(0, height, width, 10))
        self.player.play()

    # 进度条更新
    def vlc_timer_task(self):
        while True:
            time.sleep(2)
            progress = int(self.player.get_position()*100)
            self.slider_progress.setValue(progress)

    # 进度条拖动
    def vlc_progress_change(self):
        value = self.slider_progress.value()
        self.player.set_position(value/100)

    def keyPressEvent(self, event):
        # 当按下按键时触发此事件处理函数
        if event.key() == Qt.Key_Left:
            print("Left key pressed")
            self.vlc_backward()
        elif event.key() == Qt.Key_Right:
            print("Right key pressed")
            self.vlc_forward()
        elif event.key() == Qt.Key_Up:
            print("up key pressed")
            self.vlc_adjust_vol(5)
        elif event.key() == Qt.Key_Down:
            print("down key pressed")
            self.vlc_adjust_vol(-5)
        elif event.key() == Qt.Key_Space:
            print("Space key pressed")
            self.vlc_play_pause()
        elif event.key() in (Qt.Key_1, Qt.Key_2, Qt.Key_3, Qt.Key_4):
            self.adjust_ui_layout(event.key())

        print(f"其他键被按下: {event.text()}, 键码: {event.key()}")


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    Form = QtWidgets.QWidget()
    ui = vlcPlayer(Form)
    Form.show()
    Form.keyPressEvent = ui.keyPressEvent  # 将 keyPressEvent 绑定到 Form 上
    sys.exit(app.exec_())
